home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Environments / Clean 1.2.4 / StdEnv / StdList.icl < prev    next >
Encoding:
Modula Implementation  |  1997-04-02  |  9.3 KB  |  410 lines  |  [TEXT/3PRM]

  1. implementation module StdList
  2.  
  3. // ****************************************************************************************
  4. //    Concurrent Clean Standard Library Module Version 1.1
  5. //    Copyright 1995 University of Nijmegen
  6. // ****************************************************************************************
  7.  
  8. import    StdClass, StdMisc, StdEnum, StdInt, StdChar, StdBool, StdArray, StdString
  9.  
  10. // ****************************************************************************************
  11. //    Instances of overloaded functions:
  12. // ****************************************************************************************
  13.  
  14. instance ==     [a] | Eq a
  15.     where
  16.     (==) :: ![a]    ![a]    ->    Bool | Eq a
  17.     (==) [] []
  18.         = True
  19.     (==) [] _
  20.         = False
  21.     (==) [_:_] []
  22.         = False
  23.     (==) [a:as] [b:bs] 
  24.         | a == b
  25.             = as == bs
  26.         // otherwise
  27.             = False
  28.  
  29. instance < [a] | Ord a
  30.     where
  31.     (<) :: ![a]    ![a] ->    Bool | Ord a
  32.     (<) []      []
  33.         = False
  34.     (<) [] _
  35.         = True
  36.     (<) [_:_] []
  37.         = False
  38.     (<) [a:as] [b:bs]
  39.         | a < b
  40.             = True
  41.         | a > b
  42.             = False
  43.         // otherwise
  44.             = as < bs
  45.         
  46. instance length []
  47.     where
  48.     length ::![a] -> Int
  49.     length xs = acclen 0 xs
  50.     where
  51.         acclen n [x:xs] = acclen (inc n) xs
  52.         acclen n []     = n
  53.     
  54. instance % [a]
  55.     where
  56.     (%) :: ![a] !(!Int,!Int) -> [a]
  57.     (%) list (frm,to) = take (to - frm + 1) (drop frm list)
  58.     
  59.         
  60. instance toString     [x] | toChar x
  61.     where
  62.     toString::![x] -> {#Char} | toChar x
  63.     toString xs = ltosacc xs ""
  64.     where
  65.         ltosacc [h:t] acc = ltosacc t (acc +++ toString (toChar h))
  66.         ltosacc []      acc = acc
  67.     
  68. instance fromString [x] | fromChar x
  69.     where
  70.     fromString::!{#Char} -> [x] | fromChar x
  71.     fromString s = stolacc s (size s - 1) []
  72.     where
  73.         stolacc :: !String !Int u:[a] -> u:[a] | fromChar a
  74.         stolacc s i acc 
  75.             | i >= 0
  76.                 = stolacc s (dec i) [fromChar (s.[i]) : acc] 
  77.             // otherwise
  78.                 = acc
  79.     
  80. // ****************************************************************************************
  81. // standard operators
  82. // ****************************************************************************************
  83.  
  84. (!!) infixl 9::![.a] Int -> .a
  85. (!!) [] _
  86.     = abort "Subscript error in !,index too large"
  87. (!!) list i
  88.     =    index list i
  89.     where
  90.         index ::![.a] !Int -> .a
  91.         index [hd:tl] 0
  92.             = hd
  93.         index [hd:tl] n
  94.             = index tl (n - 1)
  95.         index [] _
  96.             = abort "Subscript error in !,index too large"
  97.  
  98. (++) infixr 5::![.a] u:[.a] -> u:[.a]
  99. (++) [hd:tl]    list    = [hd:tl ++ list]
  100. (++) nil         list    = list
  101.  
  102. flatten::![[.a]] -> [.a]
  103. flatten [h:t]    = h ++ flatten t
  104. flatten []        = []
  105.  
  106. isEmpty::![.a] -> Bool
  107. isEmpty    []
  108.     =    True
  109. isEmpty    _
  110.     =    False
  111.  
  112. // ****************************************************************************************
  113. // standard functions
  114. // ****************************************************************************************
  115.  
  116. drop::Int !u:[.a] -> u:[.a]
  117. drop n cons=:[a:x]    | n>0    = drop (n - 1) x
  118.                             = cons
  119. drop n []                    = []
  120.  
  121. dropLast::![.a] -> [.a] // include functions like this?? and what about dropUntil ??
  122. dropLast [a]    = []
  123. dropLast [a:b]    = [a:dropLast b]
  124. dropLast []        = abort "dropLast of []"
  125.  
  126. dropWhile :: (a -> .Bool) !u:[a] -> u:[a]
  127. dropWhile f cons=:[a:x]    | f a    = dropWhile f x
  128.                                 = cons
  129. dropWhile f []                    = []
  130.  
  131. filter::(a -> .Bool) !.[a] -> .[a]
  132. filter f [a:x]    | f a    = [a:filter f x]
  133.                         = filter f x
  134. filter f []                = []
  135.  
  136. // foldl::(.a -> .(.b -> .a)) .a ![.b] -> .a
  137. foldl op r l
  138.     :==    foldl r l
  139.     where
  140.         foldl r []        = r
  141.         foldl r [a:x]    = foldl (op r a) x
  142.  
  143. // foldr::(.a -> .(.b -> .b)) .b ![.a] -> .b
  144. foldr op r l
  145.     :== foldr r l
  146.     where
  147.         foldr r []        = r
  148.         foldr r [a:x]    = op a (foldr r x)
  149.  
  150. hd::![.a] -> .a
  151. hd [a:x]    = a
  152. hd []        = abort "hd of []"
  153.  
  154. indexList::![.a] -> [Int]
  155. indexList x = f 0 x
  156. where
  157.     f::!Int ![.a] -> [Int]
  158.     f n [a:x]    = [n:f (n+1) x]
  159.     f n []        = []
  160.  
  161. insert :: (a a -> .Bool) a !u:[a] -> u:[a];
  162. insert r x ls=:[y : ys]
  163. | r x y            =     [x : ls]
  164.                 =    [y : insert r x ys]
  165. insert _ x []     =     [x]
  166.  
  167. iterate::(a -> a) a -> .[a]
  168. iterate f x    = [x:iterate f (f x)]
  169.  
  170. last::![.a] -> .a
  171. last [a]    = a
  172. last [a:tl]    = last tl
  173. last []        = abort "last of []"
  174.  
  175. map::(.a -> .b) ![.a] -> [.b]
  176. map f [a:x]    = [f a:map f x]
  177. map f []    = []
  178.  
  179. remove :: !Int !u:[.a] -> u:[.a]
  180. remove 0 [y : ys]    =     ys
  181. remove n [y : ys]    =    [y : remove (n-1) ys]
  182. remove n []            =     []
  183.  
  184. repeatn :: .Int a -> .[a]
  185. repeatn n x    = take n (repeat x)
  186.  
  187. repeat:: a -> [a]
  188. repeat x =     cons
  189. where
  190.     cons = [x:cons]
  191.  
  192. reverse::![.a] -> [.a]
  193. reverse list = reverse_ list []
  194. where 
  195.     reverse_::![.a] u:[.a] -> u:[.a]
  196.     reverse_ [hd:tl] list    = reverse_ tl [hd:list]
  197.     reverse_ [] list        = list
  198.  
  199. scan:: (a -> .(.b -> a)) a ![.b] -> .[a]
  200. scan op r [a:x]    = [r:scan op (op r a) x]
  201. scan op r []    = [r]
  202.  
  203. span :: (a -> .Bool) !u:[a] -> (.[a],u:[a])
  204. span p list=:[x:xs]
  205.     | p x
  206.         = ([x:ys],zs)
  207.          with    (ys,zs) = span p xs
  208.      // otherwise
  209.         = ([],list)
  210. span p []
  211.     =    ([], [])
  212.  
  213. splitAt :: !Int u:[.a] -> ([.a],u:[.a])
  214. splitAt 0     xs    =    ([],xs)
  215. splitAt _     []    =    ([],[])
  216. splitAt n [x:xs]    =    ([x:xs`],xs``) 
  217. where
  218.     (xs`,xs``) = splitAt (n-1) xs
  219.  
  220. take::!Int [.a] -> [.a]
  221. take 0 _        = []
  222. take n [a:x]    = [a:take (dec n) x]
  223. take n []        = []
  224.  
  225. takeWhile::(a -> .Bool) !.[a] -> .[a]
  226. takeWhile f [a:x] | f a    = [a:takeWhile f x]
  227.                         = []
  228. takeWhile f []            = []
  229.  
  230. tl::!u:[.a] -> u:[.a]
  231. tl [a:x]    = x
  232. tl []        = abort "tl of []"
  233.  
  234. unzip::![(.a,.b)] -> ([.a],[.b])
  235. unzip []    =     ([], [])
  236. unzip [(x,y) : xys] = ([x : xs],[y : ys])
  237. where
  238.     (xs,ys) = unzip xys
  239.  
  240. zip2::![.a] [.b] -> [(.a,.b)]
  241. zip2 [a:as] [b:bs]    = [(a,b):zip2 as bs]
  242. zip2 as bs            = []
  243.  
  244. zip::!(![.a],[.b]) -> [(.a,.b)]
  245. zip (x,y) = zip2 x y
  246.  
  247. diag3:: !.[a] .[b] .[c]-> [.(a,b,c)]
  248. diag3 xs ys zs = [ (x,y,z) \\ ((x,y),z) <- diag2 (diag2 xs  ys) zs ]
  249.  
  250. //    diagonalisation: basic idea (for infinite lists):
  251. //
  252. //    diag2 xs ys = flatten [ dig2n n xs ys \\ n <- [1..] ]
  253. //    where dig2n n xs ys = [ (a,b) \\ a <- reverse (take n xs) & b <- take n ys ]
  254. //
  255. //    in the definition below this idea is adapted in order to deal with finite lists too
  256.  
  257. diag2:: !.[a] .[b] -> [.(a,b)]
  258. diag2 [] ys = []
  259. diag2 xs [] = []
  260. diag2 xs ys = [ (ae,be) \\ (a,b) <- takeall xs [] ys [], ae <- a & be <- b ]
  261. where
  262.     takeall xin xout yin yout
  263.     | morex&&morey    = [(nxout,   nyout) : takeall nxin nxout nyin     nyout ]
  264.     | morey            = [( xout,tl nyout) : takeall  xin  xout nyin (tl nyout)]
  265.     | morex            = [(nxout,    yout) : takeall nxin nxout  yin      yout ]
  266.     // otherwise
  267.                     = shift xout yout
  268.     where
  269.         (morex,nxin,nxout) = takexnext xin xout
  270.         (morey,nyin,nyout) = takeynext yin yout
  271.  
  272.         takexnext [x:xs] accu    = (True, xs,[x:accu])
  273.         takexnext []     accu     = (False,[],accu)
  274.  
  275.         takeynext [y:ys] accu    = (True, ys,accu++[y])
  276.         takeynext []     accu    = (False,[],accu)
  277.     
  278.         shift xout [_:ys]    = [(xout,ys): shift xout ys]
  279.         shift _    []         = []
  280.  
  281. // ****************************************************************************************
  282. // Boolean list
  283. // ****************************************************************************************
  284.  
  285. and::![.Bool] -> Bool
  286. and []
  287.     =    True
  288. and [b : tl]
  289.     | b
  290.         =    and tl
  291.     // otherwise
  292.         =    False
  293.  
  294. or::![.Bool] -> Bool
  295. or []
  296.     =    False
  297. or [b : tl]
  298.     | b
  299.         =    True
  300.     // otherwise
  301.         =    or tl
  302.  
  303. any::(.a -> .Bool) ![.a] -> Bool
  304. any p q    = or (map p q)
  305.  
  306. all::(.a -> .Bool) ![.a] -> Bool
  307. all p q    = and (map p q)
  308.  
  309. maxList::!.[a] -> a | Ord a
  310. maxList [a:x] = max1 a x
  311. where
  312.     max1:: a !.[a] -> a | Ord a
  313.     max1 m [hd:tl]
  314.         | hd<m        = max1 m tl 
  315.         // otherwise
  316.                     = max1 hd tl
  317.     max1 m []        = m
  318. maxList []    = abort "max of empty list"
  319.  
  320.  
  321. minList::!.[a] -> a | Ord a
  322. minList [a:x]    = min1 a x
  323. where
  324.     min1:: a !.[a] -> a | Ord a
  325.     min1 m [hd:tl]
  326.         | m<hd        = min1 m tl 
  327.         // otherwise    
  328.                     = min1 hd tl
  329.     min1 m []        = m
  330. minList []        = abort "min of empty list"
  331.  
  332. sort::!.[a] -> .[a] | Ord a
  333. sort [e:es]    = insert e (sort es)
  334. where
  335.     insert::a !u:[a] -> u:[a] | Ord a
  336.     insert a list=:[b:x]
  337.         | a<b        = [a:list]
  338.         // otherwise
  339.                     = [b:insert a x]
  340.     insert a []    = [a]
  341. sort []        = []
  342.  
  343. merge :: !u:[a] !u:[a] -> u:[a] | Ord a
  344. merge []  y            = y
  345. merge f=:[x:xs] []    = f
  346. merge f=:[x:xs] s=:[y:ys]
  347.     | x<y                = [x:merge xs s]
  348.     // otherwise
  349.                         = [y:merge f ys]
  350.  
  351. // ****************************************************************************************
  352. // On Ord
  353. // ****************************************************************************************
  354.  
  355. isMember::a !.[a] -> Bool | Eq a
  356. isMember x [hd:tl] 
  357.     | hd==x        = True 
  358.     // otherwise
  359.                 = isMember x tl
  360. isMember x []    = False
  361.  
  362. removeDup :: !.[a] -> .[a] | Eq a
  363. removeDup [x:xs] = [x:removeDup (filter ((<>) x) xs)]
  364. removeDup _      = []
  365.  
  366. removeMembers::u:[a] .[a] -> u:[a] | Eq a
  367. removeMembers x []        = x
  368. removeMembers x [b:y]    = removeMembers (remove b x) y    
  369. where
  370.     remove:: a u:[a] -> u:[a] | Eq a
  371.     remove e [a:as]
  372.         | a==e        = as
  373.         // otherwise
  374.                     = [a:remove e as]
  375.     remove e []        = []    
  376.  
  377. limit::!.[a] -> a | Eq a
  378. limit [a:cons=:[b:x]]
  379.     | a==b        = a
  380.     // otherwise
  381.                 = limit cons
  382. limit other        = abort "incorrect use of limit"
  383.  
  384. // ****************************************************************************************
  385. // On PlusMin
  386. // ****************************************************************************************
  387.  
  388. sum:: !.[a] -> a |  + , zero  a
  389. sum xs = accsum zero xs
  390. where
  391.     accsum n [x:xs] = accsum (n + x) xs
  392.     accsum n []     = n
  393.  
  394. // ****************************************************************************************
  395. // On Arith
  396. // ****************************************************************************************
  397.  
  398. prod:: !.[a] -> a | * , one  a
  399. prod xs = accprod one xs
  400. where
  401.     accprod n [x:xs] = accprod (n * x) xs
  402.     accprod n []     = n
  403.  
  404. avg:: !.[a] -> a | / , IncDec a
  405. avg [] = abort "avg called with empty list"
  406. avg x  = accavg zero zero x
  407. where
  408.     accavg n nelem [x:xs] = accavg (n + x) (inc nelem) xs
  409.     accavg n nelem []     = n / nelem
  410.